﻿using System;
using System.Diagnostics.Contracts;
using System.IO;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Windows;
using Codeplex.Reactive;
using Codeplex.Reactive.Extensions;

namespace isuka.samples.excel
{
    public class MainWindowViewModel
    {

        public MainWindowViewModel()
        {
            // Status
            StatusText = new ReactiveProperty<string>();
            StatusText.Value = "Performance.xls をドロップしてください";

            // ドラッグ
            DragEnter = new ReactiveProperty<DragEventArgs>(mode: ReactivePropertyMode.None);
            DragEnter.Subscribe(e =>
            {
                var filepath = GetSingleFilePath(e);
                StatusText.Value = filepath + " DragEnter";
                e.Effects = Domain.IsExcelFile(filepath) ? DragDropEffects.Copy : DragDropEffects.None;
                e.Handled = true;
            });

            //  ドロップされたファイルを解析して結果を返す
            //  解析作業は別スレッドで行い、完了したらサマリーを更新する
            Drop = new ReactiveProperty<DragEventArgs>(mode: ReactivePropertyMode.None);
            Summary = Drop
                        .Select(e => GetSingleFilePath(e))
                        .Where(filepath => Domain.IsExcelFile(filepath))
                        .Do(filepath =>
                        {
                            if (Summary != null)
                            {
                                Summary.Clear();
                            }
                            StatusText.Value = filepath + " Dropped";
                        })
                        .ObserveOn(Scheduler.TaskPool)
                        .SelectMany(filepath => Domain.Analysis(filepath))
                        .OnErrorRetry((Exception ex) => StatusText.Value = ex.ToString())
                        .ObserveOnUIDispatcher()
                        .Do(_ => StatusText.Value = "完了しました")
                        .ToReactiveCollection();
        }

        public ReactiveProperty<DragEventArgs> DragEnter { get; private set; }

        public ReactiveProperty<DragEventArgs> Drop { get; private set; }

        public ReactiveCollection<StrategySummary> Summary { get; set; }

        public ReactiveProperty<string> StatusText { get; set; }

        #region Private

        static string GetSingleFilePath(DragEventArgs e)
        {
            Contract.Requires(e != null);

            if (e.Data.GetDataPresent(DataFormats.FileDrop, true))
            {
                var list = e.Data.GetData(DataFormats.FileDrop, true) as string[];
                if (list.Length == 1)
                {
                    if (File.Exists(list[0]))
                    {
                        // At this point we know there is a single file.
                        return list[0];
                    }
                }
            }
            return null;
        }

        #endregion
    }
}
